﻿using System.Collections;
using Unity.VisualScripting;
using UnityEngine;

namespace Assets.Scripts.DL.Mgrs {
	public class ScreenEffectMgr : MonoBehaviour {
		public static ScreenEffectMgr Instance { get; private set; }


		Shader origin;
		[SerializeField]
		Material material;

		[Header("Wave Data")]
		[SerializeField] RippleEffect ripple;
		[SerializeField] Shader wave;

		[Header("Cut Data")]
		[SerializeField] Shader cut;
		[SerializeField] float stopTime;//切割后停顿时间
		[SerializeField] float recoverSpeed;
		[SerializeField] float offset;
		[SerializeField] float waitTime;
		float curOff = 0;

		[Header("Broken Data")]
		[SerializeField] Shader broken;
		[SerializeField] float brokenTime;
		//[SerializeField] float Speed;
		//[SerializeField] int Amount;
		//[SerializeField] Vector2 BlockSize;


		private void Awake() {
			material = new Material(wave);
#if UNITY_EDITOR
			if (material == null) {
				Debug.Log("No material");
			}
#endif
			Instance = this;
			origin = material.shader;

			//ripple = GetComponent<RippleEffect>();
		}

		/// <summary>
		/// Angle角度制
		/// </summary>
		public void CutEffect(Vector3 playerWorldPos, float curAngle = 0) {
			material.shader = cut;
			if (Mathf.Abs(curAngle) < 0.1) {
				curAngle = Random.Range(-80, 80);
			}
			var screenPos = Camera.main.WorldToScreenPoint(playerWorldPos);
			var pos = new Vector4(screenPos.x / Screen.width, screenPos.y / Screen.height, 0, 0);
			material.SetVector("_Pos", pos);
			//Debug.Log(pos);
			material.SetFloat("_Angle", curAngle);
			curOff = offset;
			material.SetFloat("_Offset", curOff);
			StartCoroutine(Recover());
		}


		public void BrokenEffect(float time = 0) {
			if (time < 0.1f) {
				time = brokenTime;
			}
			material.shader = broken;
			StartCoroutine(Wait(time));
		}

		public void WaveEffect(Vector3 reboundPos) {
			material.shader = wave;
			var pos = Camera.main.WorldToScreenPoint(reboundPos);
			var x = pos.x / Screen.width;
			var y = pos.y / Screen.height;
			ripple.Emit(new Vector2(x, y));
			//Debug.Log($"{x},{y}");

			//ripple.IsUpdate = true;
			StartCoroutine(Wait(waitTime));
		}

		IEnumerator Wait(float sec) {
			yield return new WaitForSeconds(sec);
			material.shader = origin;
			//ripple.IsUpdate = false;
		}

		IEnumerator Recover() {
			yield return new WaitForSeconds(stopTime);
			while (curOff < 0) {
				curOff = Mathf.Min(0, curOff + Time.deltaTime * recoverSpeed);
				material.SetFloat("_Offset", curOff);
				yield return null;
			}
			material.shader = origin;
		}

		private void OnRenderImage(RenderTexture source, RenderTexture destination) {
			//if (Time.timeScale > 0.9f)
			Graphics.Blit(source, destination, material);
		}
	}
}
